package fpzhan.plane.program.connect;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import fpzhan.plane.program.compose.AloneCodeBlockCompose;
import fpzhan.plane.program.compose.ComposeContent;
import fpzhan.plane.program.constant.ComposeType;
import fpzhan.plane.program.function.ChainCodeBlockFunction;
import fpzhan.plane.program.function.CodeBlockFunction;
import fpzhan.plane.program.function.ConditionFunction;
import fpzhan.plane.program.manager.JsonKeyManager;
import fpzhan.plane.program.proxy.CodeBlockProxy;
import fpzhan.plane.program.struct.CodeBlockStruct;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class ConditionCodeBlockCompose extends AloneCodeBlockCompose {


    Map<ConditionFunction, ChainCodeBlockConnect> keyConnect = new LinkedHashMap<>();

    public ConditionCodeBlockCompose() {
        this.setComposeType(ComposeType.BRANCH);
    }

//    public ConditionCodeBlockCompose(ComposeContext composeContext, Map<ConditionFunction, ChainCodeBlockConnect> keyConnect) {
//        super(composeContext);
//        this.keyConnect = keyConnect;
//    }


    public ChainCodeBlockFunction flow(Map<ConditionFunction, CodeBlockFunction> keyValue) {
        return param -> {
            for (Map.Entry<ConditionFunction, CodeBlockFunction> entry : keyValue.entrySet()) {
                boolean isUse = entry.getKey().apply(param);
                if (isUse) {
                    Set preRun = new HashSet<>(param.keySet());
                    entry.getValue().apply(param);
                    Set afterRun = new HashSet<>(param.keySet());
                    afterRun.removeAll(preRun);
                    param.remove((String[])afterRun.toArray(new String[]{}));
                }
            }
        };

    }

    @Override
    public CodeBlockFunction compose(List<CodeBlockProxy> proxys, JSONObject proxyJson, CodeBlockStruct struct, JSONObject structJson,
                                     ComposeContent composeContent) throws Exception {
        int i = 0;
        Map<ConditionFunction, CodeBlockFunction> keyValue = new HashMap<>();
        for (Map.Entry<ConditionFunction, ChainCodeBlockConnect> entry : keyConnect.entrySet()) {
            i++;
            ChainCodeBlockConnect connect = entry.getValue();
            JSONArray proxyArray = new JSONArray(new ArrayList<>());
            JSONArray structArray = new JSONArray(new ArrayList<>());
            CodeBlockFunction function = connect.compose(proxyArray, structArray, composeContent);
            proxyJson.put(JsonKeyManager.getJsonKey().branchKey + i, proxyArray);
            if (structArray != null && structArray.size() > 0) structJson.put(JsonKeyManager.getJsonKey().branchKey + i, structArray);
            keyValue.put(entry.getKey(), function);
        }
        return super.compose(proxys, proxyJson, struct, structJson, composeContent, flow(keyValue));
    }


    public Map<ConditionFunction, ChainCodeBlockConnect> getKeyConnect() {
        return keyConnect;
    }
}
